(function ($) {
  const userMessage = {
    nickName: $('#profile_block a:first').text().trim(),
    blogAge: $('#profile_block a:nth-child(3)').text().trim(),
    followers: $('#profile_block a:nth-child(5)').text().trim(),
    focus: $('#profile_block a:nth-child(7)').text().trim(),
  }
  const urls = {
    css: {
      theme: {
        atomOneDark: 'atomOneDark',
        atomOneLight: 'atomOneLight',
        github: 'github'
      }
    },
    script: {
      flexible: 'flexible',
      lineNumbers: 'lineNumbers',
      icon: '//at.alicdn.com/t/font_1416496_6jgg1n1pmu8.js'
    },
    repositories: window.rep
  }
  const icons = {
    news: '#ac-gonggao',                   // 公告
    catListTitle: '#ac-mulu',              // 侧边栏主标题
    readMore: '#ac-xiangyou',              // 首页阅读全文
    catalog: '#ac-categories',             // 随笔页随笔目录
    signature: '#ac-3banquanshengming',    // 随笔页版权声明
    writeComment: '#ac-bi',                // 写评论
    commentList: '#ac-pinglun',            // 评论列表
    weibo: '#ac-weibo',                    // 分享到微博
    wechat: '#ac-wechat',                  //分享到微信
    follow: '#ac-follow',                  //关注
    collect: '#ac-collect',                //收藏
    like: '#ac-like',                      //点赞
    back2top: '#ac-back2top',              //返回顶部
    logo: '#ac-logo',                      //logo
    pre: '#ac-pre',//上一个
    next: '#ac-next',//下一个
    date: '#ac-date',//日期
    edit: '#ac-edit',//编辑
    mark: '#ac-mark',//标签
    side: '#ac-side',//菜单
    close: '#ac-close',//关闭菜单
    github: '#ac-github',//github
    food: { //count -> 20
      pistachio: '#ac-food-pistachio',
      mochi: '#ac-food-mochi',
      cashew: '#ac-food-cashew',
      macaron: '#ac-food-macaron',
      cake: '#ac-food-cake',
      sushi: '#ac-food-sushi',
      eggyolkcake: '#ac-food-eggyolkcake',
      popsiple: '#ac-food-popsicle',
      taco: '#ac-food-taco',
      hotdog: '#ac-food-hotdog',
      pizza: '#ac-food-pizza',
      bread: '#ac-food-bread',
      popcorn: '#ac-food-popcorn',
      chips: '#ac-food-chips',
      doughnut: '#ac-food-doughnut',
      strawberry: '#ac-food-strawberry',
      pudding: '#ac-food-pudding',
      avocado: '#ac-food-avocado',
      pecan: '#ac-food-pecan',
      cookie: '#ac-food-cookie'
    }
  }
  const headerElements = [
    {
      title: '#user-msg',
      menu: '#user-msg-details'
    },
    {
      title: '#sidebar_recentposts',
      menu: '#sidebar_recentposts ul'
    },
    {
      title: '#sidebar_toptags',
      menu: '#sidebar_toptags ul'
    },
    {
      title: '#sidebar_postcategory',
      menu: '#sidebar_postcategory ul'
    },
    {
      title: '#sidebar_postarchive',
      menu: '#sidebar_postarchive ul'
    },
    {
      title: '#sidebar_topviewedposts',
      menu: '#sidebar_topviewedposts ul'
    },
    {
      title: '#sidebar_topcommentedposts',
      menu: '#sidebar_topcommentedposts ul'
    },
    {
      title: '#sidebar_topdiggedposts',
      menu: '#sidebar_topdiggedposts ul'
    }
  ]
  class ACG {
    constructor() {
      this.defaultOptions = window.userOptions;
      this.v = 'v1.5.0';
    }

    // 返回页面名称 'post' | 'index' | tag
    get pageName() {
      if ($('#post_detail').length > 0) {
        return 'post'
      }
      if ($('.day').length > 0) {
        return 'index'
      }
      if ($('#taglist_main').length > 0) {
        return 'tag'
      }
    }

    // 判断客户端 'phone' | 'pc'
    get userAgent() {
      const width = $(window).width();
      if (width <= 768) {
        return 'phone'
      }
      if (width > 768) {
        return 'pc'
      }
    }

    // 初始化
    init() {
      this.loadFiles([
        { name: urls.script.icon, type: 'jsCDN' },
        { name: urls.script.flexible, type: 'js' }
      ]);
      this.setThemeColor();
      this.setHeader();
      this.setGithub();
      this.setHeaderBackground();
      this.setFooter();
      if (this.userAgent === 'mobile') {
        this.setMobileMenuBtn();
      }
      if (this.pageName === 'post') {
        this.setPostPage();
        this.setHighlight();
        this.setLinenumbers();
        this.setCopyBtn();
        this.setCatalog();
        this.setPostSignature();
        this.setCommentsList();
      }
      if (this.pageName === 'index') {
        this.setIndexContent();
      }
      this.bundleEvents();
      this.hideLoading();
      this.setBack2Top();
    }

    // 返回顶部
    setBack2Top() {
      const option = this.defaultOptions.back2top;
      if (!option.enable) { return }
      const svg = this.iconInSvg(icons.back2top);
      let elements = $(`<div id="back2Top">${svg}</div>`)
        .appendTo('body')
        .click(() => {
          $("html, body").animate({ scrollTop: 0 }, 300);
        });
      $(window).bind("scroll", () => {
        let scrollTop = $(document).scrollTop();
        scrollTop > 0 ? elements.fadeIn(500) : elements.fadeOut(500);
      });
    }

    // 设置头部背景图
    setHeaderBackground() {
      const option = this.defaultOptions.theme.headerBackground;
      if (option === '') { return }
      $('#header-img').css({ 'background-image': `url(${option})` });
    }

    // 设置主题色
    setThemeColor() {
      const option = this.defaultOptions.theme.color;
      let themeColor = '';
      if (option === 'random') {
        themeColor = this.getRandomRgba();
      } else {
        themeColor = option;
      }
      $('head').append(`<style>:root{--ThemeColor: ${themeColor}}<style>`);
    }

    // 设置github
    setGithub() {
      const options = this.defaultOptions.github;
      if (!options.enable) { return }
      const $githubIcon = `<a href=${options.url}>${this.iconInSvg(icons.github)}</a>`
      $('#nav-list').prepend($githubIcon)
      $('#nav-list .icon').css({ 'color': `${options.color}` })
    }

    // 设置随笔签名
    setPostSignature() {
      const enable = this.defaultOptions.postSignature.enable;
      if (!enable) { return }
      const content = this.defaultOptions.postSignature.content;
      const href = location.href.indexOf('#') === -1 ? location.href : location.href.substring(0, location.href.lastIndexOf("#"));
      let elements = '';
      for (let i = 0; i < content.length; i++) {
        elements += '<p>' + content[i] + '</p>'
      }
      const $signature = `<section id='post-signature'>
                            <p>文章链接：${href}</p>
                            ${elements}
                          </sections>`;
      $('#post-details').before($signature);
    }

    // 代码块复制按钮
    setCopyBtn() {
      const pres = $('.cnblogs-markdown').find('pre');
      if (!pres.length) return;
      $.each(pres, (index, pre) => { $(pre).prepend(`<div class="copy-btns">copy</div>`); });
      $('pre').on('click', '.copy-btns', function () {
        let sel = window.getSelection();
        sel.removeAllRanges();
        let range = document.createRange();
        range.selectNode($(this).siblings('code.hljs')[0]);
        sel.addRange(range);
        let txt = sel.anchorNode.innerText;
        let area = $('<textarea name="" id="board" cols="30" rows="10"></textarea>');
        area.val(txt);
        area[0].select();
        document.execCommand('copy');
        $(this).text('copied');
      })
    }

    // 设置代码行号
    setLinenumbers() {
      const options = this.defaultOptions.lineNumbers;
      if (options.enable) {
        this.loadFiles([{ name: urls.script.lineNumbers, type: 'js' }], function () {
          hljs.initLineNumbersOnLoad();
        })
      }
    }

    // 设置代码高亮
    setHighlight() {
      const type = this.defaultOptions.highLight.type;
      const actions = {
        'atomOneDark': 'atomOneDark',
        'atomOneLight': 'atomOneLight',
        'github': 'github',
        'default': 'atomOneDark'
      }
      const handler = (status) => {
        return actions[status] || actions['default'];
      }
      this.loadFiles([{ name: handler(type), type: 'css' }]);
    }

    //---------- structure --------

    // 设置随笔目录
    setCatalog() {
      const options = this.defaultOptions.catalog;
      if (!options.enable && this.userAgent !== 'pc') { return }
      const $parentEle = $($('#cnblogs_post_body'));
      const $catalogContainer = $("<section>");
      const $ulContainer = $("<ul>");
      const titleReg = /^h[1-3]$/;
      $catalogContainer.attr("id", "catalog").append($(`<div id='catalog-title'><h3>目录</h3></div>`));
      $parentEle.children().each(function () {
        if (titleReg.test(this.tagName.toLowerCase())) {
          $(this).append("<a href='#catalog' class='title_back'></a>");
          let aEle = $("<a></a>");
          let hEle = $("<li></li>");
          aEle.attr("href", "#" + this.id).text(this.childNodes[0].nodeValue);
          hEle.attr("class", this.nodeName.toLowerCase() + "-list").append(aEle);
          $ulContainer.append(hEle);
        }
      });
      $($catalogContainer.append($ulContainer)).appendTo('body');
      // 给h1标题添加icon
      var that = this;
      $('#cnblogs_post_body:first>h1').each(function () {
        const icon = that.getRandomFoodicons();
        $(this).prepend(that.iconInSvg(icon));
      })
    }

    // 设置随笔页
    setPostPage() {
      // 随笔题目
      $('#header-img').html(`<h1>${$('#cb_post_title_url').text()}</h1>`);
      // 随笔内容
      $('header').after(`<section id="post-wrap">${$('#cnblogs_post_body').prop("outerHTML")}</section>`);
      // 随笔底部分类、标签、日期、阅读数、编辑按钮、收藏按钮、好文要顶、关注按钮
      let postCategory = '';
      let postMark = '';
      $('#BlogPostCategory a').each(function () {
        postCategory += $(this).prop("outerHTML");
      });
      $('#EntryTag a').each(function () {
        postMark += $(this).prop("outerHTML");
      });
      const postDate = $('#post-date').text();
      const postViewCount = $('#post_view_count').text();
      const editBtn = $('.postDesc> :nth-child(5)').prop("outerHTML");
      const collectBtn = $('.postDesc a:last').prop("outerHTML");
      const likeBtn = $('#green_channel_digg').prop("outerHTML");
      const followBtn = $('#green_channel_follow').prop("outerHTML");
      const $postDetails = `<section id="post-details">
                              <div id='post-date'>${this.iconInSvg(icons.date)}<span>${postDate}</span></div>
                              <div id='post-category'>${this.iconInSvg(icons.catalog)}${postCategory}</div>
                              <div id='post-mark'>${this.iconInSvg(icons.mark)}${postMark}</div>
                              <div id='post-view'>${this.iconInSvg(this.getRandomFoodicons())}<span>${postViewCount}</span></div>
                              <div id='post-edit'>${this.iconInSvg(this.getRandomFoodicons())}${editBtn}</div>
                              <div id='post-collect'>${this.iconInSvg(this.getRandomFoodicons())}${collectBtn}</div>
                              <div id='post-like'>${this.iconInSvg(this.getRandomFoodicons())}${likeBtn}</div>
                              <div id='post-follow'>${this.iconInSvg(this.getRandomFoodicons())}${followBtn}</div>
                            </section>`;
      $('#post-wrap').append($postDetails);
      // 上一篇  下一篇
      const prePost = $('#post_next_prev a:nth-child(2)').prop("outerHTML");
      const nextPost = $('#post_next_prev a:nth-child(5)').prop("outerHTML");
      let $preNextElements = '';
      $preNextElements = `<section id="post-pre-next">
                                <div id='post-pre' style="visibility:${prePost !== undefined ? 'visible' : 'hidden'}">${this.iconInSvg(icons.pre)}${prePost}</div>
                                <div id='post-next' style="visibility:${nextPost !== undefined ? 'visible' : 'hidden'}">${this.iconInSvg(icons.next)}${nextPost}</div>
                            </section>`;
      $('#post-details').after($preNextElements);
      // 显示评论列表头像
      $(".feedbackItem").each(function () {
        var avatar = $(this).children(".feedbackCon").children("span:last").html();
        avatar = avatar ? avatar.replace("http://", "https://") : "https://pic.cnblogs.com/face/sample_face.gif";
        $('<img src="' + avatar + '" class="avatar" />').prependTo($(this).children(".feedbackCon"));
      });
    }

    // 隐藏loading
    hideLoading() {
      $('#loading').fadeOut(500);
    }

    // 设置首页列表
    setIndexContent() {
      if (this.pageName === 'index') {
        let indexItems = '<section id="index-item-wrap">';
        $('.postTitle').each(function () {
          const item = `<div class='post-item'>${$(this)[0].outerHTML}</div>`;
          indexItems += item;
        })
        $('header').after(indexItems + '</section>');
        $('#header-img').html(`<h1>${userMessage.nickName}</h1>`);
        this.setIndexContentImages();
      }
    }

    // 设置首页列表背景图
    setIndexContentImages() {
      const repositoriesUrl = urls.repositories.package + '/assets/images/acg/';
      $('.post-item').each(function () {
        const random = Math.floor(Math.random() * 67) + 1;
        const imgUrl = `${repositoriesUrl + random}.jpg`;
        $(this).css({
          'background-image': `url(${imgUrl})`
        });
      });
    }

    // 设置头部
    setHeader() {
      const $background = `<div id='header-img'></div>`;
      const $userMsg = `<ul id='user-msg-details'>
                          <li>园龄：${$('#profile_block a:nth-child(3)').prop("outerHTML")}</li>
                          <li>粉丝：${$('#profile_block a:nth-child(5)').prop("outerHTML")}</li>
                          <li>关注：${$('#profile_block a:nth-child(7)').prop("outerHTML")}</li>
                        </ul>`;
      const $nickName = ` <li id='user-msg'><a href="https://www.cnblogs.com/guangzan/">${userMessage.nickName}</a>${$userMsg}</li>`;
      const $navList = $('#home #navList').html();
      const $categories = $('#blog-sidecolumn').prop("outerHTML");
      const $headerElements = `<header>
                                ${$background}
                                <ul id="nav-list">
                                  ${$nickName}
                                  ${$navList}
                                  ${$categories}
                                </ul>
                              </header>`;
      $('#page_begin_html').after($headerElements);
    }

    // 移动端菜单
    setMobileMenuBtn() {
      $('body').append(`<section id='side-btn-wrap'><div id='side-btn'><div id='side-btn-burger'></div></div></section>`);
      $('#side-btn').click(function () {
        event.preventDefault();
        if ($(this).hasClass('side-btn-active')) {
          $(this).removeClass('side-btn-active');
          $('#nav-list').css({
            'visibility': 'hidden',
            'transition': 'all 500ms ease-in-out',
            'clip-path': 'circle(30px at calc(100%) 100%)',
          });
        } else {
          $(this).addClass('side-btn-active');
          $('#nav-list').css({
            'visibility': 'visible',
            'transition': 'all 300ms ease-in-out',
            'clip-path': 'circle(100%)'
          })
        }
      })
    }

    // 设置footer
    setFooter() {
      const config = this.defaultOptions.links;
      const cr = `<div id='copyright'>
                      <span>Copyright © 2019 ${userMessage.nickName}</span>
                      <span>
                        Powered by ${'VS Code 1.x'.link('https://code.visualstudio.com/')}
                        🎉
                        Theme ${'awesCnb'.link(urls.repositories.gitee)} ${this.v}
                      </span>
                  </div>`
      let links = '<div id="links"><ul>';
      for (let i = 0; i < config.length; i++) {
        links += `<li><a href='${config[i].link}'>${config[i].name}</a></li>`;
        if (i === config.length - 1) {
          links += '</ul></div>';
        }
      }
      const $footer = `<footer>${links}${cr}</footer>`;
      $('body').append($footer);
    }

    // ------事件-----
    // 设置活跃目录标题
    setActiveCatalogTitle() {
      var that = this;
      var p = 0, t = 0;
      $(window).scroll(function (e) {
        p = $(this).scrollTop();
        if (t <= p) {
          // 向下滚动
          $('#catalog ul li').each(function () {
            const titleId = $(this).find('a').attr('href').replace(/[#]/g, "");
            const postTitle = document.querySelector(`#cnblogs_post_body [id='${titleId}']`);
            if (that.getClientReat(postTitle).top <= 50) {
              $(this).addClass('catalog-active');
              $(this).siblings().removeClass('catalog-active');
              return
            }
          })
        } else {
          for (let i = $('#catalog ul li').length - 1; i >= 0; i--) {
            const titleId = $($('#catalog ul li')[i]).find('a').attr('href').replace(/[#]/g, "");
            const postTitle = document.querySelector(`#cnblogs_post_body [id='${titleId}']`);
            if (that.getClientReat(postTitle).bottom <= 50) {
              $($('#catalog ul li')[i]).addClass('catalog-active');
              $($('#catalog ul li')[i]).siblings().removeClass('catalog-active');
              return
            }
          }
        }
        setTimeout(function () { t = p; }, 0);
      });
    }

    // 随笔页目录显示隐藏
    setCatalogEvent() {
      $(window).scroll(function () {
        $(window).scrollTop() > 300 ? $('#catalog').show() : $('#catalog').hide();
      })
    }

    // 评论列表
    setCommentsList() {
      $('.feedbackListSubtitle').append($('.feedbackManage').prop('outerHTML'));
      $('.feedbackListSubtitle>.feedbackManage:first-of-type').hide();
    }

    // 绑定事件
    bundleEvents() {
      if (this.userAgent === 'pc') {
        if (this.pageName === 'post') {
          this.setCatalogEvent()
        }
        this.mouseoverOrmouseout(headerElements);
        this.setActiveCatalogTitle();
      }
      if (this.userAgent === 'phone') {
        this.clickToggle(headerElements);
      }
    }

    //---------- tools ----------
    // 加载文件
    // [{name: '', type: ''}] js | css | jsCDN | cssCDN
    loadFiles(files, callback) {
      const cb = callback || function () { };
      const repositoriesUrl = urls.repositories.package + '/assets';
      for (let i = 0; i < files.length; i++) {
        const name = files[i].name;
        const type = files[i].type;
        const cssUrl = repositoriesUrl + '/css/' + name + '.css';
        const jsUrl = repositoriesUrl + '/js/' + name + '.min.js';
        const actions = {
          'css': () => {
            $("head").append(`<link rel="stylesheet" href="${cssUrl}">`);
          },
          'js': () => {
            $.getScript(jsUrl, () => { cb() });
          },
          'cssCDN': () => {
            $("head").append(`<link rel="stylesheet" href="${name}">`);
          },
          'jsCDN': () => {
            $.getScript(name);
          },
          'default': () => {
            console.error('Type error!');
          }
        }
        actions[type]();
      }
    }

    // 指定icon插入svg
    iconInSvg(icon) {
      return `<svg class="icon" aria-hidden="true"><use xlink:href="${icon}"></use></svg>`;
    }

    // 鼠标移入展开移出收起
    // [{rootDom: 'title', changingDom: 'menu'} ]
    mouseoverOrmouseout(elements) {
      for (let i = 0; i < elements.length; i++) {
        $(document).on('mouseover', elements[i].title, function () {
          $(elements[i].menu).stop().fadeIn(500);
        });
        $(document).on('mouseout', elements[i].title, function () {
          $(elements[i].menu).stop().fadeOut(200);
        });
      }
    }

    // 鼠标点击展开再次点击隐藏
    // [{rootDom: 'title', changingDom: 'menu'}]
    clickToggle(elements) {
      let status = 0;
      for (let i = 0; i < elements.length; i++) {
        $(document).on('click', elements[i].title, function () {
          if (status === 0) {
            $(elements[i].menu).stop().fadeIn(500);
            status = 1;
          } else {
            $(elements[i].menu).stop().fadeOut(200);
            status = 0;
          }
        });
      }
    }

    // 获取一个随机image url
    getRandomImgUrl() {
      const repositoriesUrl = urls.repositories.package + '/assets/images/acg/';
      const random = Math.floor(Math.random() * 78);
      const url = `${repositoriesUrl + random}.jpg`;
      return url;
    }

    //获取一个随机food icons
    getRandomFoodicons() {
      const random = Math.floor(Math.random() * 20);
      let iconsArray = [];
      Object.keys(icons.food).forEach(function (key) {
        iconsArray.push(icons.food[key]);
      });
      return iconsArray[random];
    }

    // 获取随机颜色
    getRandomRgba() {
      const r = Math.floor(Math.random() * 256);
      const g = Math.floor(Math.random() * 256);
      const b = Math.floor(Math.random() * 256);
      const a = 0.6;
      return `rgba(${r},${g},${b},${a})`;
    }

    // 获取元素相对与浏览器视口的位置
    getClientReat(client) {
      const { top, bottom, left, right, height, width } = client.getBoundingClientRect()
      return {
        top,
        bottom,
        left,
        right,
        height: height || bottom - top,
        width: width || right - left
      }
    }
  }
  new ACG().init();
})(jQuery);
